﻿// Copyright 2009 Mike Geise
// 
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// 
//     http://www.apache.org/licenses/LICENSE-2.0
// 
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

using Falcon.Core.Domain;

namespace Falcon.Core.Extensions
{
	using System;
	using System.Collections;
	using System.Globalization;
	using System.IO;
	using System.Text;
	using System.Web.Mvc;
	using System.Web.UI;

	public static class SelectExtension
	{
		/// <summary>
		/// Renders the drop down list using a tree structure.
		/// </summary>
		/// <param name="helper">The helper.</param>
		/// <param name="name">The name.</param>
		/// <param name="list">The list.</param>
		/// <returns></returns>
		public static string TreeDropDownList(this HtmlHelper helper, string name, SelectList list)
		{
			var builder = new StringBuilder();

			using (var writer = new StringWriter(builder, CultureInfo.InvariantCulture))
			{
				using (var html = new XhtmlTextWriter(writer))
				{
					html.AddAttribute(HtmlTextWriterAttribute.Id, name);
					html.AddAttribute(HtmlTextWriterAttribute.Name, name);
					html.RenderBeginTag(HtmlTextWriterTag.Select);

					if (list != null)
					{
						OptionsRecursive(html, list, list.Items);
					}

					html.RenderEndTag();
				}
			}

			return builder.ToString();
		}

		/// <summary>
		/// Renders a localized drop down list.
		/// </summary>
		/// <param name="helper">The helper.</param>
		/// <param name="name">The name.</param>
		/// <param name="list">The list.</param>
		/// <param name="localize">if set to <c>true</c> [localize].</param>
		/// <returns></returns>
		public static string DropDownList(this HtmlHelper helper, string name, SelectList list, bool localize)
		{
			var builder = new StringBuilder();

			using (var writer = new StringWriter(builder, CultureInfo.InvariantCulture))
			{
				using (var html = new XhtmlTextWriter(writer))
				{
					html.AddAttribute(HtmlTextWriterAttribute.Id, name);
					html.AddAttribute(HtmlTextWriterAttribute.Name, name);
					html.RenderBeginTag(HtmlTextWriterTag.Select);

					if (list != null)
					{
						OptionsLocalized(html, list, list.Items);
					}

					html.RenderEndTag();
				}
			}

			return builder.ToString();
		}

		/// <summary>
		/// Renders the options using recursion (tree list).
		/// </summary>
		/// <param name="html">The HTML.</param>
		/// <param name="list">The list.</param>
		/// <param name="items">The items.</param>
		private static void OptionsRecursive(HtmlTextWriter html, SelectList list, IEnumerable items)
		{
			foreach (var item in items)
			{
				var value = Eval(item, list.DataValueField);

				if (value.Equals(list.SelectedValue))
				{
					html.AddAttribute(HtmlTextWriterAttribute.Selected, "selected");
				}

				html.AddAttribute(HtmlTextWriterAttribute.Value, value.ToString());
				html.RenderBeginTag(HtmlTextWriterTag.Option);
				html.Write(Eval(item, list.DataTextField).ToString().Indent(Convert.ToInt32(Eval(item, "Depth"), CultureInfo.InvariantCulture)));
				html.RenderEndTag();

				var childern = Eval(item, "Childern") as IList;

				if (childern != null && childern.Count > 0)
				{
					OptionsRecursive(html, list, childern);
				}
			}
		}

		/// <summary>
		/// Renders the localized options.
		/// </summary>
		/// <param name="html">The HTML.</param>
		/// <param name="list">The list.</param>
		/// <param name="items">The items.</param>
		private static void OptionsLocalized(HtmlTextWriter html, SelectList list, IEnumerable items)
		{
			foreach (var item in items)
			{
				var value = Eval(item, list.DataValueField);

				if (value.Equals(list.SelectedValue))
				{
					html.AddAttribute(HtmlTextWriterAttribute.Selected, "selected");
				}

				var text = Eval(item, list.DataTextField).ToString().ToLowerInvariant();

				html.AddAttribute(HtmlTextWriterAttribute.Value, value.ToString());
				html.RenderBeginTag(HtmlTextWriterTag.Option);
				html.Write(Resources.GetByKey(string.Concat("select.option.", text)));
				html.RenderEndTag();
			}
		}

		/// <summary>
		/// Evals the specified container.
		/// </summary>
		/// <param name="container">The container.</param>
		/// <param name="expression">The expression.</param>
		/// <returns></returns>
		private static object Eval(object container, string expression)
		{
			var value = container;

			if (expression.HasValue())
			{
				value = DataBinder.Eval(container, expression);
			}

			return value;
		}
	}
}